package org.xxpay.pay.channel.witbytespay;

import com.alibaba.fastjson.JSONObject;
import org.xxpay.core.common.constant.PayConstant;
import org.xxpay.core.common.util.MyLog;
import org.xxpay.core.common.util.PayDigestUtil;
import org.xxpay.core.entity.PayOrder;
import org.xxpay.pay.channel.BasePayNotify;
import org.xxpay.pay.channel.saaspay.SaaspayConfig;
import org.xxpay.pay.channel.saaspay.SaaspayPayNotifyService;
import org.xxpay.pay.channel.saaspay.SaaspayUtil;
import org.xxpay.pay.util.MyHttp;

import javax.servlet.http.HttpServletRequest;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;

import static org.xxpay.pay.channel.witbytespay.WitbytespayUtil.getSignatureByMD5;

public class WitbytespayPayNotifyService extends BasePayNotify {
    private static final MyLog _log = MyLog.getLog(WitbytespayPayNotifyService.class);
    private static final String logPrefix = "【处理"+ WitbytespayConfig.CHANNEL_NAME+"支付回调】";

    @Override
    public String getChannelName() {
        return WitbytespayConfig.CHANNEL_NAME;
    }

    @Override
    public JSONObject doNotify(Object notifyData) {
        _log.info("====== 开始处理{}支付回调通知 ======", getChannelName());
        HttpServletRequest request = (HttpServletRequest) notifyData;
        JSONObject retObj = buildRetObj();
        Map<String, String> payContext = new HashMap();

        String respString = WitbytespayConfig.RETURN_VALUE_ERROR;
        try {
            PayOrder payOrder = verifyPayParams(request, payContext);
            if( payOrder == null ) { //验证参数失败
                retObj.put(PayConstant.RESPONSE_RESULT, SaaspayConfig.RETURN_VALUE_ERROR);
                return retObj;
            }
            //订单已经支付完成
            if(payOrder.getStatus() == PayConstant.PAY_STATUS_SUCCESS || payOrder.getStatus() == PayConstant.PAY_STATUS_COMPLETE){
                retObj.put(PayConstant.RESPONSE_RESULT, SaaspayConfig.RETURN_VALUE_SUCCESS);
                return retObj;
            }
            //上游通知 状态
            String channelOrderNo = payContext.get("queryId"); //上游订单号

            int updatePayOrderRows = commonService.payOrderService.updateStatus4Success(payOrder.getPayOrderId(), channelOrderNo);
            if (updatePayOrderRows != 1) {
                _log.error("{}更新支付状态失败,将payOrderId={},更新payStatus={}失败", logPrefix, payOrder.getPayOrderId(), PayConstant.PAY_STATUS_SUCCESS);
                retObj.put(PayConstant.RESPONSE_RESULT, "处理订单失败");
                return retObj;
            }
            _log.error("{}更新支付状态成功,将payOrderId={},更新payStatus={}成功", logPrefix, payOrder.getPayOrderId(), PayConstant.PAY_STATUS_SUCCESS);
            payOrder.setStatus(PayConstant.PAY_STATUS_SUCCESS);

            // 业务系统后端通知
            baseNotify4MchPay.doNotify(payOrder, true);
            _log.info("====== 完成处理{}支付回调通知 ======", getChannelName());
            respString = SaaspayConfig.RETURN_VALUE_SUCCESS;
        } catch (Exception e) {
            _log.error(e, logPrefix + "处理异常");
        }
        retObj.put(PayConstant.RESPONSE_RESULT, respString);
        return retObj;
    }

    /**
     * 验通知参数
     * @return
     */
    public PayOrder verifyPayParams(HttpServletRequest request, Map<String, String> payContext) {

        JSONObject paramObj = MyHttp.getParam(request);
        _log.info("获取请求参数：{}", paramObj);

        // 校验结果是否成功
        String sh_order = paramObj.getString("ordercode");                      // 商户支付单号
        String pt_order = paramObj.getString("ordercode");                      // 三方平台的单号
        String money = paramObj.getString("total_amount");              // 交易金额
        String status = paramObj.getString("notification_status");		    // 支付状态
        String sign = paramObj.getString("sign"); 		         // 签名

        // 验证状态
        if (!"success".equals(status)) {
            _log.error("状态错误 ,payOrderId={}, status={}", pt_order, status);
            return null;
        }

        // 查询payOrder记录
        String payOrderId = sh_order;
        PayOrder payOrder = commonService.payOrderService.findByPayOrderId(payOrderId);
        if (payOrder == null) {
            _log.error("Can't found payOrder form db. payOrderId={}, ", payOrderId);
            return null;
        }

        WitbytespayConfig witbytespayConfig = new WitbytespayConfig(getPayParam(payOrder));
        // 验证签名
        paramObj.remove("sign");
        String signStr = PayDigestUtil.sortedStr(paramObj);
        String signValue = null;
        try {
            signValue = getSignatureByMD5(signStr,witbytespayConfig.getSecret());
            if(!sign.equals(signValue)) {
                _log.error("验证签名失败. payOrderId={}, 签名结果：{}", payOrderId, signValue);
                return null;
            }
            payContext.put("queryId", sh_order);
            return payOrder;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    public static void main(String[] args) throws NoSuchAlgorithmException {
        String obj = "{\"buyerUsername\":\"lvd***@sina.cn\",\"msgType\":\"trade.notify\",\"payTime\":\"2024-03-04 11:13:10\",\"buyerCashPayAmt\":\"1\",\"connectSys\":\"UNIONPAY\",\"sign\":\"102ADF0DD2F8AA80034A47399F0239708C2FA0011CA8116C7145D1A9BBE2105B\",\"merName\":\"中保付测试商户(中保付测试商户)\",\"mid\":\"898201612345678\",\"PY\":\"sCQa\",\"invoiceAmount\":\"1\",\"settleDate\":\"2024-03-04\",\"billFunds\":\"支付宝余额:1\",\"buyerId\":\"2088502274981260\",\"mchntUuid\":\"6d47dc12a4c847eaba2eb456d201d5cd\",\"tid\":\"88880001\",\"instMid\":\"H5DEFAULT\",\"receiptAmount\":\"1\",\"couponAmount\":\"0\",\"cardAttr\":\"BALANCE\",\"targetOrderId\":\"2024030422001481261431766243\",\"signType\":\"SHA256\",\"billFundsDesc\":\"支付宝余额支付0.01元。\",\"orderDesc\":\"支付测试\",\"seqId\":\"01314800336N\",\"merOrderId\":\"P01202403041113021970001\",\"targetSys\":\"Alipay 2.0\",\"totalAmount\":\"1\",\"createTime\":\"2024-03-04 11:11:28\",\"buyerPayAmount\":\"1\",\"notifyId\":\"80d3b915-29bf-4b31-b149-aaff6a571576\",\"subInst\":\"100200\",\"status\":\"TRADE_SUCCESS\"}";
        JSONObject jsonObject = JSONObject.parseObject(obj);
        jsonObject.remove("sign");
        String sortJson = PayDigestUtil.sortedStr(jsonObject)+"impARTxrQcfwmRijpDNCw6hPxaWCddKEpYxjaKXDhCaTCXJ6";
        System.out.println("sortJson="+sortJson);
        String sign = SaaspayUtil.generateSHA256Signature(sortJson);
        String apiSign = "E3F161080C45CAD90BC1BAA091F7834BBBC22C0D9D10A598B05AF1E63F993815";
        System.out.println("sign="+sign);
    }

}
